package contegor.scire.core;

import java.util.Map;

/**
 * Interface for the elements in the system that can be root or source of {@link Link} instances.
 * 
 * @version $Revision: 1.8 $
 * @author  Héctor Cirbián Pousa ($Author: hector $)
 */
@Version("$Id: Connectable.java,v 1.8 2010-02-01 10:55:38 hector Exp $")
public interface Connectable {

  /**
   * Returns a {@link Map} with the {@link Link} instances which its source is <code>this</code>.
   * The {@link Map} values are the {@link Link} instances, and the keys are the {@link Id} of the targets of them, 
   * 
   * @return {@link Map}. It can be empty, but never <code>null</code>. Is not modifiable.
   */
  public Map<Id,Link> getLinks();

  /**
   * Returns a {@link Map} with the {@link Link} instances which its source is <code>this</code> and who's
   * targets are between the two {@link Id} passed as parameter. The {@link Map} values are the {@link Link}
   * instances, and the keys are the {@link Id} of the targets of them, 
   * 
   * @param from low end {@link Id} (inclusive) from where the {@link Link}s are recovered.
   * @param to high end {@link Id} (inclusive) to which the {@link Link}s are recovered.
   * @return {@link Map}. It can be empty, but never <code>null</code>. Is not modifiable.
   */
  public Map<Id,Link> getLinks(Id from, Id to);

  /**
   * Returns a {@link Map} with the {@link Link} instances which its source is <code>this</code> and who's
   * targets are greater or equal to the {@link Id} passed as parameter. The {@link Map} values are the
   * {@link Link} instances, and the keys are the {@link Id} of the targets of them, 
   * 
   * @param from low end {@link Id} (inclusive) from where the {@link Link}s are recovered.
   * @return {@link Map}. It can be empty, but never <code>null</code>. Is not modifiable.
   */
  public Map<Id,Link> getTopLinks(Id from);

  /**
   * Returns a {@link Map} with the {@link Link} instances which its source is <code>this</code> and who's
   * targets are less or equal to the {@link Id} passed as parameter. The {@link Map} values are the
   * {@link Link} instances, and the keys are the {@link Id} of the targets of them, 
   * 
   * @param id {@link Id} from where do the retreival.
   * @return {@link Map}. It can be empty, but never <code>null</code>. Is not modifiable.
   */
  public Map<Id,Link> getBottomLinks(Id from);

  /**
   * Returns the {@link Link} instance which its source is <code>this</code> and who's
   * targets is the least {@link Id} greater or equal to the given {@link Id}. 
   * 
   * @param id {@link Id} from where do the retreival.
   * @return the floor {@link Link}. It can be <code>null</code>.
   */
  public Link getCeilLink(Id id);

  /**
   * Returns the {@link Link} instance which its source is <code>this</code> and who's
   * targets is the greatest {@link Id} less than or equal to the given {@link Id}. 
   * 
   * @param id {@link Id} from where the {@link Link}s are recovered.
   * @return the floor {@link Link}. It can be <code>null</code>.
   */
  public Link getFloorLink(Id id);

  /**
   * Returns the count of {@link Link} instances which its source is <code>this</code>.
   */
  public int getLinksCount();

  /**
   * Returns the {@link Link} which its source is <code>this</code> and its <i>target</i> is identified by
   * the {@link Id} passed as parameter.
   * 
   * @param target {@link Id} of the sought {@link Link}.
   * @return {@link Link}</code> sought. It will be null if there is no such {@link Link}.
   */
  public Link getLink(Id target);

  /**
   * Shows if <code>this</code> has a connection to the element identified by the <code>target</code>
   * parameter.
   * 
   * @param target {@link Id} looked for.
   * @return <code>boolean</code> true if there is such a <code>{@link Link}</code>
   */
  public boolean isLinkedWith(Id target);

  /** Returns the <code>Connectable</code> creation time. */
  public long getCreationTime();

  /**
   * This method will allow queries to check if <code>this</code> is visible to them. As a general rule,
   * modifications done by one transaction will be only visible to queries that belong to it, until commit
   * is done. Then it will be visible to all. The detailed rules are:
   * <li>If <code>this</code> has been marked as erased, but the commit not been done, it will return <b>(this.transactionId != transactionId)</b>.</li>
   * <li>If the transaction that created <code>this</code> has not done the commit, it will return <code>(this.transactionId == transactionId)</code>.</li>
   * <li>If <code>this</code> is not currently affected by any transaction, it will return <b>true</b>.</li>
   */
  public boolean isVisibleTo(TransactionId transactionId);

}